package com.joker.demo.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.joker.demo.admin.domain.po.EnvironmentMonitorPO;
import com.joker.demo.admin.domain.po.ThreadPoolMonitorPO;
import com.joker.demo.admin.mapper.EnvironmentMonitorMapper;
import com.joker.demo.admin.mapper.ThreadPoolMonitorMapper;
import com.joker.demo.admin.service.DataCleanupService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 数据清理服务实现类
 *
 * @author : feixiang.li
 * @since : 2025-01-27 10:00
 */
@Slf4j
@Service
public class DataCleanupServiceImpl implements DataCleanupService {

    @Resource
    private EnvironmentMonitorMapper environmentMonitorMapper;

    @Resource
    private ThreadPoolMonitorMapper threadPoolMonitorMapper;

    /**
     * 定时清理监控数据任务
     * 每天凌晨2点执行一次
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void scheduledCleanupMonitorData() {
        log.info("开始执行定时清理监控数据任务...");
        
        try {
            int totalDeleted = cleanupAllMonitorData(10);
            log.info("定时清理监控数据任务执行完成，共删除 {} 条记录", totalDeleted);
        } catch (Exception e) {
            log.error("定时清理监控数据任务执行失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cleanupEnvironmentMonitorData(int days) {
        try {
            log.info("开始清理环境监控数据，保留最近 {} 天的数据", days);
            
            // 计算截止时间
            LocalDateTime cutoffTime = LocalDateTime.now().minusDays(days);
            
            // 构建查询条件
            LambdaQueryWrapper<EnvironmentMonitorPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.lt(EnvironmentMonitorPO::getCreateTime, cutoffTime);
            
            // 分批删除，避免一次性删除过多数据
            int totalDeleted = 0;
            int batchSize = 1000;
            
            while (true) {
                // 查询要删除的记录ID
                queryWrapper.last("LIMIT " + batchSize);
                List<EnvironmentMonitorPO> recordsToDelete = environmentMonitorMapper.selectList(queryWrapper);
                
                if (recordsToDelete.isEmpty()) {
                    break;
                }
                
                // 批量删除
                List<Long> idsToDelete = recordsToDelete.stream()
                        .map(EnvironmentMonitorPO::getId)
                        .collect(java.util.stream.Collectors.toList());
                
                int deletedCount = environmentMonitorMapper.deleteBatchIds(idsToDelete);
                totalDeleted += deletedCount;
                
                log.info("环境监控数据清理进度：已删除 {} 条记录", totalDeleted);
                
                // 如果删除的记录数小于批次大小，说明已经删除完毕
                if (deletedCount < batchSize) {
                    break;
                }
            }
            
            log.info("环境监控数据清理完成，共删除 {} 条记录", totalDeleted);
            return totalDeleted;
            
        } catch (Exception e) {
            log.error("清理环境监控数据失败", e);
            throw new RuntimeException("清理环境监控数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cleanupThreadPoolMonitorData(int days) {
        try {
            log.info("开始清理线程池监控数据，保留最近 {} 天的数据", days);
            
            // 计算截止时间
            LocalDateTime cutoffTime = LocalDateTime.now().minusDays(days);
            
            // 构建查询条件
            LambdaQueryWrapper<ThreadPoolMonitorPO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.lt(ThreadPoolMonitorPO::getCreateTime, cutoffTime);
            
            // 分批删除，避免一次性删除过多数据
            int totalDeleted = 0;
            int batchSize = 1000;
            
            while (true) {
                // 查询要删除的记录ID
                queryWrapper.last("LIMIT " + batchSize);
                List<ThreadPoolMonitorPO> recordsToDelete = threadPoolMonitorMapper.selectList(queryWrapper);
                
                if (recordsToDelete.isEmpty()) {
                    break;
                }
                
                // 批量删除
                List<Long> idsToDelete = recordsToDelete.stream()
                        .map(ThreadPoolMonitorPO::getId)
                        .collect(java.util.stream.Collectors.toList());
                
                int deletedCount = threadPoolMonitorMapper.deleteBatchIds(idsToDelete);
                totalDeleted += deletedCount;
                
                log.info("线程池监控数据清理进度：已删除 {} 条记录", totalDeleted);
                
                // 如果删除的记录数小于批次大小，说明已经删除完毕
                if (deletedCount < batchSize) {
                    break;
                }
            }
            
            log.info("线程池监控数据清理完成，共删除 {} 条记录", totalDeleted);
            return totalDeleted;
            
        } catch (Exception e) {
            log.error("清理线程池监控数据失败", e);
            throw new RuntimeException("清理线程池监控数据失败", e);
        }
    }

    @Override
    public int cleanupAllMonitorData(int days) {
        log.info("开始清理所有监控数据，保留最近 {} 天的数据", days);
        
        int envDeleted = cleanupEnvironmentMonitorData(days);
        int threadPoolDeleted = cleanupThreadPoolMonitorData(days);
        
        int totalDeleted = envDeleted + threadPoolDeleted;
        log.info("所有监控数据清理完成，环境监控删除 {} 条，线程池监控删除 {} 条，总计 {} 条", 
                envDeleted, threadPoolDeleted, totalDeleted);
        
        return totalDeleted;
    }
}
